package io.github.xyzboom.cj

class LineBasedStringBuilder(
    private val startLine: Int = 0,
    private val endLine: Int = Int.MAX_VALUE
) {
    // key: Line, value: builder
    private val lineBuilder = hashMapOf<Int, StringBuilder>()

    fun set(startLine: Int, startColumn: Int, value: String) {
        if (startLine !in this.startLine..endLine) {
            return
        }
        val builder = lineBuilder.getOrPut(startLine) { StringBuilder() }
        val needSpaceNum = startColumn - builder.length - 1
        if (needSpaceNum <= 0) {
            builder.setRange(startColumn - 1, startColumn + value.length, value)
        } else {
            builder.append(" ".repeat(needSpaceNum))
            builder.append(value)
        }
    }

    override fun toString(): String {
        val sorted = lineBuilder.entries.sortedBy { (key, _) -> key }
        val result = StringBuilder()
        var lineNum = 1

        fun appendEmptyLineUntil(lineIs: Int) {
            while (lineNum < lineIs) {
                result.appendLine()
                lineNum++
            }
        }

        for ((i, v) in sorted.withIndex()) {
            val (line, builder) = v
            appendEmptyLineUntil(line)
            result.append(builder)
        }

        return result.toString()
    }
}